package io.openmessaging.io;

import com.intel.pmem.llpl.AnyHeap;
import com.intel.pmem.llpl.MemoryAccessor;

import java.nio.ByteBuffer;

/**
 * 提高 size() 方法速度，
 * 代价是只能单线程追加写，不能随机写，不能多线程写；
 * 可以多线程读
 */
public class MemoryBlockWrapper implements IO {

    private MemoryAccessor memory;
    private volatile long writePos = 0;

    public MemoryBlockWrapper(AnyHeap heap, long size) {
        memory = heap.allocateMemoryBlock(size);
    }

    public long size() {
        return writePos;
    }

    public void delete() {
        writePos = 0;
    }

    public int read(ByteBuffer dst, long position) {
        byte[] buf = dst.array();
        int size = dst.remaining();
        memory.copyToArray(position, buf, dst.position(), size);
        dst.position(dst.position() + size);
        return size;
    }

    @Override
    public void copyFrom(IO src, long srcOffset, long length) {
        if (src instanceof MemoryBlockWrapper) {
            memory.copyFrom(((MemoryBlockWrapper) src).memory, srcOffset, writePos, length);
            writePos += length;
        } else {
            IO.super.copyFrom(src, srcOffset, length);
        }
    }

    /**
     * 从文件结尾追加
     * 非线程安全
     */
    public long write(ByteBuffer... buffers) {
        long i = writePos;
        for (ByteBuffer buf : buffers) {
            byte[] array = buf.array();
            memory.copyFromArray(array, buf.position(), i, buf.remaining());
            i += buf.remaining();
            buf.position(buf.limit());
        }
        writePos = i;
        return i;
    }
}
